#include "app_adc_processing.h"
#include "arm_math.h"
#include "elog.h"
#include "app_sys.h"
#include "sai.h"
#include "cmsis_os.h"
#include "math.h"
#include "board.h"

extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
extern osSemaphoreId_t adc1_trans_semHandle;

static fft_buff_t fft_buff_adc;

#define AVERAGE_NUMBER 10
static float average[AVERAGE_NUMBER] = {0};

/* 滑动平均 */
static float average_conversion(float value)
{
    float aver = 0;
    static uint8_t count = 0;
    float temp = 0;

    /* 滑动 */
    for (uint8_t i = (AVERAGE_NUMBER - 1); i > 0; i--)
    {
        average[i] = average[i - 1];
    }

    average[0] = value;

    temp = 0;
    if (count < AVERAGE_NUMBER)
    {
        /* 累加 */
        for (uint8_t i = 0; i < (count + 1); i++)
        {
            temp += average[i];
        }

        /* 求平均 */
        aver = temp / (count + 1);
        count++;
    }
    else
    {
        /* 累加 */
        for (uint8_t i = 0; i < AVERAGE_NUMBER; i++)
        {
            temp += average[i];
        }

        /* 求平均 */
        aver = temp / AVERAGE_NUMBER;
        count++;
    }

    return aver;
}

/* ADC 数据采集 */
static uint8_t adc_start_acquisition(void)
{
    /* 开始采集数据 */
    HAL_SAI_Receive_DMA(&hsai_BlockA3, (uint8_t *)fft_buff_adc.adc_sample_buf, ADC_BUFFER_SIZE);

    /* 等待数据采集完成*/
    while (osSemaphoreAcquire(adc1_trans_semHandle, osWaitForever) != osOK)
    {
        osDelay(1);
    }

    return 0;
}

/* ADC 数据处理 */
static uint8_t adc_data_processing(void)
{
    uint8_t ret = 0;
    float adc_phase_ch1 = 0;  // adc 通道 1 相位
    float adc_phase_ch2 = 0;  // adc 通道 2 相位
    float adc_phase_diff = 0; // 相位差

    /* 分包 */
    for (uint32_t i = 0; i < FFT_DATA_NUM; i++)
    {
        /* 由于adc6140开启了4个通道，所以采集的时候进行4个数据的偏移 */
        /* 实部 */
        fft_buff_adc.complex_input_buf[0][i].data_i = (float)((int16_t)fft_buff_adc.adc_sample_buf[4 * i + 0]);
        fft_buff_adc.complex_input_buf[1][i].data_i = (float)((int16_t)fft_buff_adc.adc_sample_buf[4 * i + 1]);

        /* 虚部 */
        fft_buff_adc.complex_input_buf[0][i].data_q = 0;
        fft_buff_adc.complex_input_buf[1][i].data_q = 0;
    }

    /* FFT */
    arm_cfft_f32(&arm_cfft_sR_f32_len1024, &fft_buff_adc.complex_input_buf[0][0], 0, 1); /* 执行 FFT */
    arm_cfft_f32(&arm_cfft_sR_f32_len1024, &fft_buff_adc.complex_input_buf[1][0], 0, 1); /* 执行 FFT */

    /* 取模 即计算幅度 */
    // arm_cmplx_mag_f32(&fft_buff_adc.complex_input_buf[0][0], &fft_buff_adc.amp_output_buf[0][0], FFT_DATA_NUM);
    // arm_cmplx_mag_f32(&fft_buff_adc.complex_input_buf[1][0], &fft_buff_adc.amp_output_buf[1][0], FFT_DATA_NUM);

    /* 计算相位 */
    /* 通道 1 计算相位 */
    adc_phase_ch1 = atan2f(fft_buff_adc.complex_input_buf[0][ADC_TARGET_LOCATION].data_i, fft_buff_adc.complex_input_buf[0][ADC_TARGET_LOCATION].data_q);
    adc_phase_ch1 = (adc_phase_ch1 * 180.0f) / PI;

    /* 通道 2 计算相位 */
    adc_phase_ch2 = atan2f(fft_buff_adc.complex_input_buf[1][ADC_TARGET_LOCATION].data_i, fft_buff_adc.complex_input_buf[1][ADC_TARGET_LOCATION].data_q);
    adc_phase_ch2 = (adc_phase_ch2 * 180.0f) / PI;

    /* 相位差 */
    adc_phase_diff = adc_phase_ch1 - adc_phase_ch2;

    /* 处理相位模糊问题 */
    if (adc_phase_diff > 180)
    {
        adc_phase_diff -= 360;
    }
    else if (adc_phase_diff < -180)
    {
        adc_phase_diff += 360;
    }

    /* 滑动平均处理 */
    adc_phase_diff = average_conversion(adc_phase_diff);
    // printf(" adc_phase_diff : %f \r\n", adc_phase_diff);

    app_sys_para.display_value = (int16_t)(adc_phase_diff > 0 ? adc_phase_diff + 0.5 : adc_phase_diff + 360);

    return ret;
}

/* ADC 数据处理任务 */
void app_adc_processing_task(void)
{

    while (1)
    {
        if (bsp_adc6140_dev_get_status() == 0)
        {
            /* 数据采集 */
            adc_start_acquisition();

            /* 数据处理 */
            adc_data_processing();
        }

        /* 任务延时 */
        osDelay(100);
    }
}
